/*
    Project:        Home Power Control
    File:           HPCSensorValue.cpp
    Author:         christian@karunamusic.at
    Date:           12.2015
    Description:
 */

#include <stdexcept>
#include <sstream>
#include "HPCSensorValue.h"

HPCSensorValue::HPCSensorValue( )
    : HPCValue()
{
}

HPCSensorValue::HPCSensorValue( const char* val, ValueType vt )
    : HPCValue(val, vt)
{
}

HPCSensorValue::HPCSensorValue( HPCSensorValue& ref )
    : HPCValue()
{
    *this = ref;
}

HPCSensorValue::~HPCSensorValue()
{
    for ( const HPCAlarmValue* mn : m_Min )
    {
        delete mn;
    }
    for ( const HPCAlarmValue* mx : m_Max )
    {
        delete mx;
    }
}

const HPCValue* HPCSensorValue::Min( unsigned int ndx )
{
    if ( ndx < m_Min.size() )
    {
        return m_Min[ndx];
    }

    return nullptr;
}

const HPCValue* HPCSensorValue::Max( unsigned int ndx )
{
    if ( ndx < m_Max.size() )
    {
        return m_Max[ndx];
    }

    return nullptr;
}

void HPCSensorValue::addAlarm( const char* Min, const char* Max )
{
    if ( Min )
    {
        m_Min.push_back( new HPCAlarmValue(Min,m_Type) );
    }
    if ( Max )
    {
        m_Max.push_back( new HPCAlarmValue(Max,m_Type) );
    }
}

int HPCSensorValue::isAlarm()
{
    int ret = 0;

    for ( unsigned int i = 0; i < m_Min.size(); i++ )
    {
        //if ( (double)(*this) <= (double)(*m_Min[i]) )
        if ( *this <= *m_Min[i] )
        {
            if ( !m_Min[i]->Alarmed() )
            {
                ret = i * -1;
                m_Min[i]->Alarmed(true);
            }
        }
        else
        {
            m_Min[i]->Alarmed(false);
        }
    }

    for ( unsigned int j = 0; j < m_Max.size(); j++ )
    {
        if ( *this >= *m_Max[j] )
        {
            if ( !m_Max[j]->Alarmed() )
            {
                ret = j;
                m_Max[j]->Alarmed(true);
            }
        }
        else
        {
            m_Max[j]->Alarmed(false);
        }
    }

    return ret;
}

HPCSensorValue& HPCSensorValue::operator= (bool v)
{
    m_Val.asBoolean = v;
    if ( m_Type == undefined )
        m_Type = Boolean;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (char v)
{
    m_Val.asSignedChar = v;
    if ( m_Type == undefined )
        m_Type = SignedChar;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (unsigned char v)
{
    m_Val.asUnsignedChar = v;
    if ( m_Type == undefined )
        m_Type = UnsignedChar;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (int v)
{
    m_Val.asSignedInt = v;
    if ( m_Type == undefined )
        m_Type = SignedInt;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (unsigned int v)
{
    m_Val.asUnsignedInt = v;
    if ( m_Type == undefined )
        m_Type = UnsignedInt;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (long v)
{
    m_Val.asSignedLong = v;
    if ( m_Type == undefined )
        m_Type = SignedLong;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (unsigned long v)
{
    m_Val.asUnsignedLong = v;
    if ( m_Type == undefined )
        m_Type = UnsignedLong;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (float v)
{
    m_Val.asFloat = v;
    if ( m_Type == undefined )
        m_Type = Float;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (double v)
{
    m_Val.asDouble = v;
    if ( m_Type == undefined )
        m_Type = Double;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (const std::string& v)
{
    std::istringstream is(v);
    switch ( m_Type )
    {
        case Boolean:
            is >> m_Val.asBoolean;
        break;
        case SignedChar:
            is >> m_Val.asSignedChar;
        break;
        case UnsignedChar:
            is >> m_Val.asUnsignedChar;
        break;
        case SignedInt:
            is >> m_Val.asSignedInt;
        break;
        case UnsignedInt:
            is >> m_Val.asUnsignedInt;
        break;
        case SignedLong:
            is >> m_Val.asSignedLong;
        break;
        case UnsignedLong:
            is >> m_Val.asUnsignedLong;
        break;
        case Float:
            is >> m_Val.asFloat;
        break;
        case Double:
            is >> m_Val.asDouble;
        break;
        default:
            throw std::runtime_error( "HPCSensorValue=: type not defined" );
        break;
    }

    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (const HPCValue& v)
{
    if ( m_Type == undefined )
        m_Type = v.Type();
    *this = (double)v;
    m_Timestamp = dateTime();
    return *this;
}

HPCSensorValue& HPCSensorValue::operator= (const HPCSensorValue& v)
{
    if ( m_Type == undefined )
        m_Type = v.m_Type;
    m_Val = v.m_Val;
    m_Timestamp = v.m_Timestamp;
    return *this;
}
